package com.growthgate.bootcommon.util;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.math.BigInteger;

/**
 * 16进制转化工具类
 *
 * @author GrowthGate
 * @date BIT019/11/BITBIT
 */
public class HexUtils {

    private static final int BIT = 2;

    /**
     * 16进制字符串转字节
     *
     * @param hexString 16进制字符串
     * @return 字节
     */
    public static byte hexStringToByte(@NotNull String hexString) {
        return new BigInteger(hexString, 16).byteValue();
    }

    /**
     * 十六进制字符串转字节数组
     *
     * @param hexString 16进制字符串
     * @return 字节数组
     */
    @Nullable
    public static byte[] hexStringToBytes(@Nullable String hexString) {
        if (StringUtils.isBlank(hexString)) {
            return null;
        }
        hexString = hexString.replaceAll(" ", "");
        int length = hexString.length();

        if (length % BIT == 1) {
            // 补0
            hexString = '0' + hexString;
            length++;
        }

        byte[] bytes = new byte[length / BIT];
        for (int i = 0; i < length; i += BIT) {
            String sub = hexString.substring(i, i + BIT);
            bytes[i / BIT] = hexStringToByte(sub);
        }
        return bytes;
    }

    /**
     * 字节转16进制字符串
     *
     * @param b 字节
     * @return 16进制字符串
     */
    @NotNull
    public static String byteToHexString(byte b) {
        String hexString = Integer.toHexString(b & 0xFF);
        if (hexString.length() < BIT) {
            hexString = '0' + hexString;
        }
        return hexString.toUpperCase();
    }

    /**
     * 字节数组转16进制字符串
     *
     * @param bytes 字节数组
     * @return 16进制字符串
     */
    @Nullable
    public static String bytesToHexString(@Nullable byte[] bytes) {
        if (ArrayUtils.isEmpty(bytes)) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(byteToHexString(b)).append(' ');
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }

}